package Domain;

import org.apache.log4j.Logger;

import java.io.Serializable;
import java.util.Collection;

import Persistance.MySqlUtilityManagment;
import test.Persistance.CollaborationAlgoTest;
import BusinessLogic.Exceptions.DataAlreadyExistException;
import Domain.MySqlAccessors.MySqlRecommendationProxy;

public class RecommendationSet implements IRecommendationSet, Serializable {

    private MySqlRecommendationProxy m_recommendations;
    static Logger logger = Logger.getLogger("MovieSystem.Domain.RecommendationSet");

    public RecommendationSet(MySqlUtilityManagment sql){
        m_recommendations = new MySqlRecommendationProxy(sql);
    }

    public RecommendationSet(MySqlRecommendationProxy proxy) {
        m_recommendations = proxy;
    }

    public Recommendation get(String user, String item) {
        return m_recommendations.getRecord(user,item);
    }

    public void add(Recommendation r) throws DataAlreadyExistException {

        try {
            m_recommendations.addRecord(r);
        } catch (DataAlreadyExistException e) {
            logger.info("Recommendation "+r.getUserName()+"/"+r.getMovieName()+" already exist in the DB");
            throw new DataAlreadyExistException(r.getUserName()+"/"+r.getMovieName());
        }

    }

    public void remove(Recommendation r) {
        String movieId = r.getMovieName();
        String userId = r.getUserName();
        m_recommendations.deleteRecord(userId,movieId);

            logger.info("No recomendation for movie: "+movieId+". ignoring comnand.");

    }

    public double getRank(String user, String movie){
        double ans = 0;

        Recommendation r = get(user, movie);
        if(r != null){
            ans = r.getUserRank();
        }
        else {
            logger.info("Get rank ("+user+","+movie+") does not exist. assuming 0.");
        }

        return ans;
    }

    public boolean hasRank(String user, String movie){
        return (get(user,movie) != null);
    }

    public double getAvgRank(String user) {
        double ans = m_recommendations.getUserRank(user);
        logger.debug("Average rank ("+user+") = "+ans);
        return ans;
    }

    public Collection<Recommendation> getUserItems(String user) {
        return m_recommendations.getUserItems(user);        
    }

    public Collection<Recommendation> getMovieItems(String movie) {
        return m_recommendations.getMovieItems(movie);        
    }

    public Collection<String> getJointItems(String user1, String user2) {
        return m_recommendations.getJointItems(user1,user2);
    }

    public Collection<Recommendation> values(){
        return m_recommendations.values();
    }

    public Collection<String> getUsers(){
        return m_recommendations.getUsers();
    }

    public Collection<String> getRecommendingUsers(String movie){
        return m_recommendations.getUsers(movie);
    }

    // AVG
    public double getMovieRank(String movie){
        return m_recommendations.getMovieRank(movie);
    }
    
    public int getHighestRank(String movie){
        return m_recommendations.getHighestRank(movie);
    }
    
    public int getLowestRank(String movie){
        return m_recommendations.getLowestRank(movie);
    }
}
